﻿using FolderTag.Core;
using FolderTag.DB;
using FolderTag.Model;
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;
using Microsoft.VisualBasic.FileIO;
using SQLBuilder.Core.Extensions;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace FolderTag.FolderView
{
    /// <summary>
    /// FolderControl.xaml 的交互逻辑
    /// </summary>
    public partial class FolderControl : UserControl
    {

        MainWindow _MainWindow;
        TagEqualityComparer _TagEqualityComparer = new TagEqualityComparer();
        ImageSource _DefaultFileImage = null;

        /// <summary>
        /// 当前过滤标签列表
        /// </summary>
        public HashSet<int> LayerTagList = null;

        public FolderControl()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 窗口加载完毕
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            LoadPath();
            var defaultFileImage = new MahApps.Metro.IconPacks.UniconsImageExtension(MahApps.Metro.IconPacks.PackIconUniconsKind.FileLine);
            defaultFileImage.Brush = new SolidColorBrush(Colors.White);
            _DefaultFileImage = defaultFileImage.ProvideValue(null) as ImageSource;
            _MainWindow = this.TryFindParent<MainWindow>();
        }

        #region 目录显示相关
        /// <summary>
        /// 加载目录
        /// </summary>
        /// <param name="parentPath">加载路径</param>
        /// <param name="tagIds"></param>
        /// <param name="selectPath"></param>
        public void LoadPath(string parentPath = "", HashSet<int> tagIds = null, string selectPath = "")
        {
            PathItem selectPathItem = null;//优先级大于selectIndex,用户操作
            int selectIndex = -1;//软件自身刷新处理
            bool isSuccess = false;
            if ("cur".Equals(parentPath))
                parentPath = ParentPath_TextBox.Text;

            if (ParentPath_TextBox.Text == parentPath)
                selectIndex = ListView_Path.SelectedIndex;

            List<PathItem> pathList = new List<PathItem>();
            if (string.IsNullOrEmpty(parentPath))
            {
                var drives = DriveInfo.GetDrives();
                foreach (var drive in drives)
                {
                    pathList.Add(new PathItem(drive));
                }
                isSuccess = true;
            }
            else
            {
                //路径兼容化处理
                parentPath = parentPath.Replace("/", "\\");
                //SMB,Share 等网络共享目录 
                if (UtilHelper.IsShare(parentPath))
                {
                    int strLen = parentPath.Length;
                    if (parentPath.LastIndexOf("\\") == strLen - 1)
                        parentPath = parentPath.Substring(0, strLen - 1);
                    var nrList = NetFolderConnection.GetShareDictionary(parentPath);
                    foreach (var nr in nrList)
                    {
                        PathItem pathItem = new PathItem(nr, $"{parentPath}\\");
                        pathList.Add(pathItem);
                    }
                    isSuccess = true;
                }
                else
                {
                    //目录路径兼容
                    if (!"\\".Equals(parentPath.Substring(parentPath.Length - 1, 1)))
                        parentPath = $"{parentPath}\\";
                    //系统目录
                    var directoryInfo = new DirectoryInfo(parentPath);
                    if (directoryInfo.Exists && (directoryInfo.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
                    {
                        var dbList = FolderPathDb.QueryList(parentPath);
                        var sysList = directoryInfo.GetFileSystemInfos();
                        bool isUserSelect = string.IsNullOrEmpty(selectPath);
                        foreach (var fileSystem in sysList)
                        {
                            #region 过滤隐藏和系统文件
                            if (!SystemConfig.Config.ShowAllFile)
                            {
                                if ((fileSystem.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
                                    continue;
                                else if ((fileSystem.Attributes & FileAttributes.System) == FileAttributes.System)
                                    continue;
                            }
                            #endregion
                            PathItem pathItem = new PathItem(fileSystem, dbList);
                            if (tagIds == null || pathItem.TagList.Any(x => tagIds.Contains(x.Id)))
                            {
                                pathList.Add(pathItem);
                                if (!isUserSelect && pathItem.Path == selectPath)
                                    selectPathItem = pathItem;
                            }
                        }
                        LayerTagList = tagIds;
                        isSuccess = true;
                    }

                }
            }
            if (isSuccess)
            {
                ListView_Path.ItemsSource = pathList.OrderByDescending(x => x.Type);
                if (selectPathItem != null)
                    ListView_Path.SelectedItem = selectPathItem;
                else
                    ListView_Path.SelectedIndex = selectIndex;
                if (parentPath != ParentPath_TextBox.Text && pathList.Count > 0)
                {
                    if (ListView_Path.SelectedItem != null)
                        ListView_Path.ScrollIntoView(ListView_Path.SelectedItem);
                    else
                        ListView_Path.ScrollIntoView(pathList[0]);
                }
                ParentPath_TextBox.Text = parentPath;
            }
        }

        /// <summary>
        /// 目录双击访问
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListView_Path_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                PathItem pathItem = ListView_Path.SelectedItem as PathItem;
                if (pathItem != null)
                {
                    LoadPath(pathItem.GetFullPath());
                }
            }
        }

        /// <summary>
        /// 目录列表选择事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListView_Path_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            PathItem pathItem = ListView_Path.SelectedItem as PathItem;
            PathDetail_Grid.DataContext = pathItem;
        }

        /// <summary>
        /// 目录详细展示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PathDetail_Grid_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            PathItem pathItem = e.NewValue as PathItem;
            Visibility vis = Visibility.Hidden;
            PathDetail_TagLIst_WrapPanel.Children.Clear();
            if (pathItem != null)
            {
                ImageSource image = _DefaultFileImage;
                if (pathItem.Type == EPathType.Image)
                    image = UtilHelper.GetImage(pathItem.GetFullPath());
                PathDetail_Preview.Source = image;

                vis = pathItem.Id > -1 ? Visibility.Visible : Visibility.Hidden;
                foreach (var tag in pathItem.TagList)
                {
                    TagButton button = new TagButton();
                    button.DataContext = TagItem.Clone(tag);
                    PathDetail_TagLIst_WrapPanel.Children.Add(button);
                }
                PathDetail_PathExtension_TextBox.IsEnabled = !string.IsNullOrEmpty(pathItem.PathExtension);
            }
            PathDetail_Grid.Visibility = vis;
        }

        #endregion

        /// <summary>
        /// 设置目录标签列表
        /// </summary>
        /// <param name="pathItem"></param>
        private void PathSetTagList(PathItem pathItem, string action, IList tempList)
        {
            List<TagItem> saveList = new List<TagItem>();
            if (!string.IsNullOrEmpty(action))
            {
                //如果是清空则没有必要再转换一次
                if (!"Path_ClearTag".Equals(action))
                {
                    foreach (var item in tempList)
                    {
                        saveList.Add((TagItem)item);
                    }
                }
                if ("Path_AppendTag".Equals(action))//追加的时候取并集
                    saveList = pathItem.TagList.Union(saveList, _TagEqualityComparer).ToList();
                else if ("Path_SubTag".Equals(action))//减去的时候取交集
                    saveList = pathItem.TagList.Except(saveList, _TagEqualityComparer).ToList();

                pathItem.TagList = saveList;
            }

            var isSuccess = false;
            if (pathItem.Id > 0)
                isSuccess = FolderPathDb.Update(pathItem);
            else
                isSuccess = FolderPathDb.Add(pathItem);

            if (!isSuccess)
                _MainWindow.ShowModalMessageExternal("设置标签", "失败,数据库未知错误", MessageDialogStyle.Affirmative);

            LoadPath(pathItem.ParentPath, LayerTagList);
        }

        /// <summary>
        /// 覆盖绑定目录标签列表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_NeedSelectTag_Click(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            var pathItem = PathDetail_Grid.DataContext as PathItem;
            if (pathItem != null)
            {
                var tempList = _MainWindow.Ctl_TagManage.Tag_ListBox.SelectedItems;
                if (tempList.Count == 0)
                    _MainWindow.ShowModalMessageExternal("设置标签", "请先选择标签", MessageDialogStyle.Affirmative);
                else
                {
                    PathSetTagList(pathItem, button.Name, tempList);
                }
            }
        }

        /// <summary>
        /// 清空标签
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_ClearTag_Click(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            var pathItem = PathDetail_Grid.DataContext as PathItem;
            if (pathItem != null)
            {
                PathSetTagList(pathItem, button.Name, new ArrayList());
            }
        }

        /// <summary>
        /// 刷新目录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Refresh_Click(object sender, RoutedEventArgs e)
        {
            ListView_Path.Items.Filter = null;
            LoadPath("cur");
        }

        /// <summary>
        /// 地址栏路径变更(快捷按钮路径栏)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ParentPath_TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            ParentPath_StackPanel.Children.Clear();
            Button mian = new Button();
            mian.Content = "计算机";
            mian.Click += Button_LoadPath;
            ParentPath_StackPanel.Children.Add(mian);
            if (!string.IsNullOrEmpty(ParentPath_TextBox.Text))
            {
                var pathList = ParentPath_TextBox.Text.Split("\\");
                for (int i = 0; i < pathList.Length; i++)
                {
                    var path = pathList[i];
                    if (!string.IsNullOrEmpty(path))
                    {
                        Label label = new Label();
                        label.VerticalContentAlignment = VerticalAlignment.Center;
                        label.Content = "\\";
                        ParentPath_StackPanel.Children.Add(label);
                        Button pathbtn = new Button();
                        pathbtn.Content = $"{path}";
                        pathbtn.DataContext = i;
                        pathbtn.Click += Button_LoadPath;
                        ParentPath_StackPanel.Children.Add(pathbtn);
                    }
                }
            }
            if (ParentPath_StackPanel.ScrollOwner != null)
                ParentPath_StackPanel.ScrollOwner.ScrollToRightEnd();
        }

        private void Button_LoadPath(object sender, RoutedEventArgs e)
        {
            Button btn = sender as Button;
            string loadPath = "";
            string selectPath = "";
            if (btn.DataContext != null)
            {
                int pathIndex = (int)btn.DataContext + 1;
                if (pathIndex > 0)
                {
                    var tempList = ParentPath_TextBox.Text.Split("\\");
                    for (var i = 0; i < pathIndex; i++)
                    {
                        string tempStr = tempList[i];
                        if (!string.IsNullOrEmpty(tempStr) || i < 2)
                            loadPath += tempList[i] + "\\";
                    }
                    if (pathIndex < tempList.Length)
                    {
                        selectPath = tempList[pathIndex];
                    }
                }
            }
            LoadPath(loadPath, selectPath: selectPath);
        }

        private void Button_EditPath_Click(object sender, RoutedEventArgs e)
        {
            bool changeInput = ParentPath_TextBox.Visibility == Visibility.Collapsed;
            ParentPath_TextBox.Visibility = changeInput ? Visibility.Visible : Visibility.Collapsed;
            if (!changeInput)
                LoadPath("cur");
        }

        /// <summary>
        /// 设置目录名称(重命名)和目录描述
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_SetPathAndDesc_Click(object sender, RoutedEventArgs e)
        {
            var pathItem = PathDetail_Grid.DataContext as PathItem;
            if (pathItem != null)
            {
                try
                {
                    //重命名目录
                    string newName = PathDetail_PathName_TextBox.Text.Trim();
                    if (pathItem.Path != newName && !string.IsNullOrEmpty(newName))
                    {
                        string fullPath = pathItem.GetFullPath();
                        if (Directory.Exists(fullPath))
                            FileSystem.RenameDirectory(fullPath, newName);
                        else if (File.Exists(fullPath))
                        {
                            string newExtension = PathDetail_PathExtension_TextBox.Text.Trim();
                            if (!".".Equals(newExtension.Substring(0, 1)))
                                newExtension = $".{newExtension}";
                            newName = $"{newName}{newExtension}";
                            FileSystem.RenameFile(fullPath, newName);
                        }
                        pathItem.Path = newName;
                    }
                }
                catch
                {
                    _MainWindow.ShowModalMessageExternal("重命名失败", "请检查是否被占用或不存在！", MessageDialogStyle.Affirmative, _MainWindow.MetroDialogSettings);
                }
                pathItem.Desc = PathDetail_Desc_TextBox.Text;
                PathSetTagList(pathItem, null, null);
            }
        }

        /// <summary>
        /// 目录列表按键定位（例如按a，跳转到a开头的目录）
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListView_Path_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            string searchstr = e.Text;
            var list = ListView_Path.Items;
            int listLen = list.Count;
            int findIndex = -1;
            int startIndex = ListView_Path.SelectedIndex + 1;
            for (int x = 2; x > 0; x--, startIndex = 0)
            {
                for (int i = startIndex; i < listLen; i++)
                {
                    string compareStr = (list[i] as PathItem).Path.Substring(0, 1);
                    if (searchstr.Equals(compareStr))
                    {
                        findIndex = i;
                        break;
                    }
                }
                if (findIndex != -1)
                    break;
            }
            if (findIndex != -1)
            {
                ListView_Path.SelectedIndex = findIndex;
                ListView_Path.ScrollIntoView(ListView_Path.SelectedItem);
            }
        }

        /// <summary>
        /// 当前目录过滤器
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        private bool FilterPath(object item)
        {
            return (item as PathItem).Path.Contains(SearchPath_TextBox.Text);
        }

        /// <summary>
        /// 当前目录过滤搜索
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_SearchPath_Click(object sender, RoutedEventArgs e)
        {
            ListView_Path.SelectedIndex = -1;
            ListView_Path.Items.Filter = FilterPath;
        }

        /// <summary>
        /// 搜索所有子目录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_SearchAllPath_Click(object sender, RoutedEventArgs e)
        {

        }

        /// <summary>
        /// 资源管理器打开目录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Browser_Click(object sender, RoutedEventArgs e)
        {
            Button btn = sender as Button;
            string browserPath = ParentPath_TextBox.Text;
            if (btn.DataContext != null)
            {
                PathItem pathItem = btn.DataContext as PathItem;
                if (pathItem != null)
                {
                    browserPath = pathItem.GetFullPath().ToString();
                }
            }
            if (!string.IsNullOrEmpty(browserPath))
                System.Diagnostics.Process.Start("explorer.exe", browserPath);
            else
                _MainWindow.ShowModalMessageExternal("打开失败", "目录不能为空", MessageDialogStyle.Affirmative, _MainWindow.MetroDialogSettings);

        }
    }


    public class TagEqualityComparer : IEqualityComparer<TagItem>
    {
        public bool Equals(TagItem x, TagItem y)
        {
            return x.Id == y.Id;
        }

        public int GetHashCode([DisallowNull] TagItem obj)
        {
            return obj.GetHashCode();
        }
    }
}
